package dosgi.core.proxy.invocationhandler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

import dosgi.core.util.MethodParameterBuilder;
import dosgi.distribution.remote.RemoteInvocationClient;


/**
 * Implementation of InvocationHandler which uses message oriented middleware to pass method 
 * invocations to remote services.
 * 
 * @author Jaroslaw Janik
 */
public class MoMInvocationHandler implements InvocationHandler {

	private Class<?> clazz;
	private BundleContext context;
	private String queueName;
	
	public MoMInvocationHandler(Class<?> clazz, BundleContext context, String queueName) {
		super();
		this.clazz = clazz;
		this.context = context;
		this.queueName = queueName;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		try {
			ServiceReference<?> reference = context.getServiceReference(RemoteInvocationClient.class.getName());
			
			RemoteInvocationClient invoker = (RemoteInvocationClient) context.getService(reference);
			
			return invoker.invoke(clazz.getName(), method.getName(), getParameters(method, args), new HashMap<String ,String>(), queueName);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}
	
	private Map<Class<?>, Object> getParameters(Method method, Object[] args) {
		if (args == null) {
			return new LinkedHashMap<Class<?>, Object>();
		}
		
		MethodParameterBuilder parameters = new MethodParameterBuilder();
		
		Class<?>[] classes = method.getParameterTypes();
		for (int i = 0; i < classes.length; ++i) {
			parameters.put(classes[i], args[i]);
		}
		
		return parameters.get();
	}
}
